%{
/* Frunk tokenizer */

#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include "parser.h"

static char buffer[1024];

void
yyerror(const char *format, ...)
{
  va_list ap;

  fprintf(stderr, "Line %d: ", yylineno);
  va_start(ap, format);
  vfprintf(stderr, format, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

int
yywrap(void)
{
  return 1;
}

%}

a			[aA]
b			[bB]
c			[cC]
d			[dD]
e			[eE]
f			[fF]
g			[gG]
h			[hH]
i			[iI]
j			[jJ]
k			[kK]
l			[lL]
m			[mM]
n			[nN]
o			[oO]
p			[pP]
q			[qQ]
r			[rR]
s			[sS]
t			[tT]
u			[uU]
v			[vV]
x			[xX]
y			[yY]
w			[wW]
z			[zZ]

letter			[a-zA-Z]

digit			[0-9]

%x STRMODE ESCCHARMODE

%%

[ \t\h\v\n]+		/* ignore whitespace */ ;

#.*			/* ignore comment */ ;

{a}{d}{d}{r}{e}{s}{s}	{ return TOK_ADDRESS; }

{c}{o}{m}{m}{e}{n}{t}	{ return TOK_COMMENT; }

{c}{o}{m}{m}{u}{n}{i}{t}{y}	{ return TOK_COMMUNITY; }

{d}{e}{s}{c}{r}{i}{p}{t}{i}{o}{n}	{ return TOK_DESCRIPTION; }

{d}{e}{v}{i}{c}{e}	{ return TOK_DEVICE; }

{d}{i}{r}{e}{c}{t}{o}{r}{y}	{ return TOK_DIRECTORY; }

{e}{m}{a}{i}{l}		{ return TOK_EMAIL; }

{f}{r}{o}{m}		{ return TOK_FROM; }

{h}{t}{m}{l}{o}{u}{t}{p}{u}{t}	{ return TOK_HTMLOUTPUT; }

{i}{n}{t}{e}{r}{f}{a}{c}{e}	{ return TOK_INTERFACE; }

{n}{o}{t}{i}{f}{y}	{ return TOK_NOTIFY; }

{p}{o}{l}{l}{i}{n}{g}	{ return TOK_POLLING; }

{r}{e}{m}{i}{n}{d}{e}{r}	{ return TOK_REMINDER; }

{t}{i}{t}{l}{e}		{ return TOK_TITLE; }

{t}{o}			{ return TOK_TO; }

{u}{r}{l}		{ return TOK_URL; }

\"			{
			  buffer[0]='\0';
			  BEGIN STRMODE;
			}

<STRMODE>[^"\n\\]*["\n\\]	{
				  switch(yytext[yyleng-1])
				  {
				    case '\n':
				      yyerror("unterminated character string");
				    case '"':
				      strncat(buffer, yytext, yyleng-1);
				      yylval.string=buffer;
				      BEGIN INITIAL;
				      return TOK_STRING;
				    case '\\':
				      strncat(buffer, yytext, yyleng-1);
				      BEGIN ESCCHARMODE;
				      break;
				    default:
				      yyerror("this should not happen");
				      BEGIN INITIAL;
				  }
				}

<ESCCHARMODE>.|\n	{
			  switch(yytext[0])
			  {
			    case 'n':
			      yytext[0]='\n';
			      break;
			    case '\n':
			      yytext[0]='\\';
			      unput('\n');
			  }
			  strncat(buffer, &yytext[0], 1);
			  BEGIN STRMODE;
			}

{digit}+		{
			  yylval.intval=atoi(yytext);
			  return TOK_NUMBER;
			}

.|\n			{ return yytext[0]; }

%%

